#ifndef _REACTOR_H
#define _REACTOR_H

#ifndef _WIN32

#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/epoll.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include <malloc.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/ioctl.h>
#include <stdarg.h>
#include <fcntl.h>

#else

#include <malloc.h>
#include <winsock2.h>

#endif

#include <types.h>
#include <errno.h>

#include <reactor_queue.h>
#include <reactor_rbtree.h>
#include <reactor_radix.h>
#include <reactor_sys.h>
#include <reactor_event.h>


#define EVENT_ASSIGN 0
#define EVENT_SET 1
#define EVENT_CLEAR 2

#define EVENT_AIO_SUSPEND 0
#define EVENT_AIO_UNSUSPEND 1

#ifdef _WIN32
#pragma comment(lib, "ws2_32.lib")
#endif

#ifdef _DEBUG
#define __(fmt, arg...) printf(fmt, ##arg)
#else 
#define __(fmt, arg...)
#endif

#ifndef _USE_ISOC99B
#define assert(value) {if(!value) {printf("BUG:File:%s Func:%s(), Line:%d\n", "reactor.c", "__unsupported", __LINE__);getchar();}}
#else
#define assert(value) {if(!value) {printf("BUG:File:%s Func:%s(), Line:%d\n", __FILE__, __func__, __LINE__);getchar();}}
#endif

#ifdef _WIN32
static inline uint64_t __event_get_sys_time()
{
	return (uint64_t)GetTickCount();
}
#else
static inline uint64_t __event_get_sys_time()
{
	return (uint64_t)clock();
}
#endif

extern struct event_syscall win32_select;
extern struct event_syscall epoll;


/*
 *  Here is all the advance function.
 */
int __event_base_init(struct event_base *base, 
                       void *(*memalloc)(size_t), 
                       void (*memfree)(void *), 
                       void *(*memrealloc)(void *, size_t), 
                       struct event_syscall *syscall);
struct event_base *__event_base_new(void *(*memalloc)(size_t), 
                                    void (*memfree)(void *), 
                                    void *(*memrealloc)(void *, size_t), 
                                    struct event_syscall *syscall);
int event_add(struct event *ev);
int __event_set(struct event *ev,
                int sockfd,
                int mode, 
				void(*func)(struct event *, u_int, struct evbuf *, void *), 
				void(*dtor)(struct event *, u_int, struct evbuf *, void *), 
                void *arg);
void __event_set_base(struct event *ev, struct event_base *base);
int __event_set_watch(struct event *ev, int watch);
int __event_unset_watch(struct event *ev, int watch);
void __event_active(struct event *ev);
void __event_deactive(struct event *ev);
int __event_del(struct event *ev);

int __event_aio_post(struct event *ev, struct evbuf *evbuf, int io);
int __event_iopool_post(struct event *ev, char *data, int len, int io);
int __event_dispatch(struct event_base *base);

#endif
